﻿
using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using XnaColor = Microsoft.Xna.Framework.Color;
namespace ColonisatorGame
{
    public abstract class InteractionObject
    {
        /// <summary>
        /// La Texture2D représantant l'affichage de l'objet
        /// </summary>
        public Texture2D Texture { get; set; }

        /// <summary>
        /// Pour identification éventuelle
        /// </summary>
        public string AssetName { get; set; }

        /// <summary>
        /// Donne le rectagle de situation absolu :
        ///  -> sans l'application du zoomLevel
        ///  -> sans la gestion de l'offset
        /// </summary>
        public Rectangle AbsoluteRectangle { get; set; }

        /// <summary>
        /// Retourne le rectangle auquel on applique ou non le zoom défini
        /// </summary>
        /// <param name="aZoomLevel">Si > 0, zoom appliqué</param>
        /// <returns></returns>
        public Rectangle GetRectangle(double aZoomCoef = 0)
        {
            return aZoomCoef > 0 ? ApplyZoomLevel(aZoomCoef) : this.AbsoluteRectangle;
        }

        /// <summary>
        /// Couleur de base appliquée à la texture lors du Draw
        /// </summary>
        public XnaColor BaseColor { get; set; }

        public InteractionObject(string texturePath)
        {
            this.AssetName = texturePath;
        }

        public virtual void Update(GameTime gameTime)
        {
        }

        public virtual void Draw(SpriteBatch spriteBatch, double aZoomCoef)
        {
            // Affichage de l'objet
            spriteBatch.Draw(this.Texture, this.GetRectangle(aZoomCoef), this.BaseColor);
        }

        public Rectangle ApplyZoomLevel(double aZoomLevel)
        {
            return new Rectangle(this.AbsoluteRectangle.X, this.AbsoluteRectangle.Y,
                Convert.ToInt32(this.AbsoluteRectangle.Width * aZoomLevel), 
                Convert.ToInt32(this.AbsoluteRectangle.Height * aZoomLevel));
        }

        /// <summary>
        /// Affecte les attributs du rectangle de position et dimensions de l'objet.
        /// Sont prises en compte les dimensions des cadres fixes.
        /// Certaines positions peuvent dépendre d'un autre.
        /// </summary>
        /// <typeparam name="T">Le type dont l'objet dépend pour le positionnement</typeparam>
        /// <param name="hud">Le GameHUD</param>
        /// <param name="dependsOn">l'instance de T</param>
        public virtual void SetAbsoluteRectangle<T>(GameHUD hud, T dependsOn) where T : InteractionObject
        {
            this.AbsoluteRectangle = new Rectangle
                (Convert.ToInt32(hud.menuInteractions.Cadre.Width - hud.fenetrePrincipale.Offset.X),
                 Convert.ToInt32(hud.menuHaut.Cadre.Height - hud.fenetrePrincipale.Offset.Y),
                 Convert.ToInt32(this.Texture.Width),
                 Convert.ToInt32(this.Texture.Height));
        }

        /// <summary>
        /// Détermine si la souris survole le cadre
        /// </summary>
        /// <param name="mouseRec"></param>
        /// <returns></returns>
        public bool IsMouseOvered(Rectangle mouseRec, double aZoomCoef)
        {
            return this.GetRectangle(aZoomCoef).Intersects(mouseRec) && !IsFullTransparentLocation(mouseRec, aZoomCoef);
        }

        public void MoveToRectange(Rectangle destination)
        {
            this.AbsoluteRectangle = new Rectangle(destination.X, destination.Y, this.AbsoluteRectangle.Width, this.AbsoluteRectangle.Height);
        }

        private bool IsFullTransparentLocation(Rectangle mouseRec, double aZoomCoef)
        {
            // transposition de la position de la souris dans le référentiel de la texture
            var X = mouseRec.X - this.GetRectangle(aZoomCoef).X;
            var Y = mouseRec.Y - this.GetRectangle(aZoomCoef).Y;

            var colorData = new XnaColor[1];
            this.Texture.GetData<XnaColor>(0, new Rectangle(X, Y, 1, 1), colorData, 0, 1);

            // récupération de la couleur du pixel dans textureData
            return colorData[0].A == 0;
        }
    }
}
